package com.huc.other.stream;

import com.huc.design.behavior.chain.base.Student;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * parallelStream 是并行流 Stream是顺序流
 */
public class StreamDemo {
    public static void main(String[] args) {
        //createStream();
        //tranfor();
        //map();
        //flatMap();
        //filter();
        sorted();
    }

    //构造 Stream 流的方式
    private static void createStream() {
        Stream stream = Stream.of("a", "b", "c");
        String[] strArray = new String[]{"a", "b", "c"};
        //数组构建
        stream = Stream.of(strArray);
        stream = Arrays.stream(strArray);

        List<String> list = Arrays.asList(strArray);
        //集合构建
        stream = list.stream();
        stream.forEach(System.out::println);
    }

    /**
     * 注意: 一个 Stream 流只可以使用一次，这段代码为了简洁而重复使用了数次，因此会抛出 stream has already been operated upon or closed 异常。
     */
    //Stream 流的之间的转换
    private static void tranfor() {
        Stream<String> stream = Stream.of("a", "b", "c");
        //转字符串
        String str = stream.collect(Collectors.joining(","));
        //转数组
        String[] array = stream.toArray(String[]::new);

        //转集合
        List<String> list = stream.collect(Collectors.toList());
        ArrayList<String> arrayList = stream.collect(Collectors.toCollection(ArrayList::new));
        //转set数组
        Set<String> set = stream.collect(Collectors.toSet());

        //转map
        List stuList = new ArrayList(2);
        stuList.add(new Student(1, "张三", 12));
        stuList.add(new Student(2, "李四", 13));

        HashMap<String, String> map = (HashMap) stuList.stream().collect(Collectors.toMap(Student::getId, Student::getName));
        System.out.println(map);

    }

    //Stream 流的 map 使用
    private static void map() {
        List<String> list = Arrays.asList("zhangSan", "liSi", "wangWu");
        System.out.println(String.format("转换之前的数据:%s", list));
        //使用字符串方法转换
        List<String> strList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
        System.out.println(String.format("转换之后的数据:%s", strList));
        //使用Integer数据转换
        List<String> numList = Arrays.asList("1", "2", "3");
        System.out.println(String.format("转换之前的数据:%s", numList));
        List<Integer> numList2 = numList.stream().map(Integer::valueOf).collect(Collectors.toList());
        System.out.println(String.format("转换之后的数据:%s", numList2));
        //做计算
        System.out.println(String.format("做计算之前的数据:%s", numList));
        List<Double> lists = numList2.stream().map(n -> Math.pow(n, 2)).collect(Collectors.toList());
        System.out.println(String.format("做计算之后的数据:%s", lists));
    }

    /**
     * 接收一个函数作为参数，将流中的每个值都换成另一个流，然后把所有流连接成一个流。
     */
    private static void flatMap() {

        List<String> list = Arrays.asList("a,b,c", "1,2,3");
        Stream<String> s3 = list.stream().flatMap(s -> {
            //将每个元素转换成一个stream
            String[] split = s.split(",");
            Stream<String> s2 = Arrays.stream(split);
            return s2;
        });
        s3.forEach(System.out::println);// a b c 1 2 3
    }


    /**
     * Stream 流的 filter 使用
     * filter：过滤流中的某些元素
     * limit(n)：获取n个元素
     * skip(n)：跳过n元素，配合limit(n)可实现分页
     * distinct：通过流中元素的 hashCode() 和 equals() 去除重复元素
     */
    private static void filter() {
        List<String> list = Arrays.asList("张三", "李四", "王五", "zhaoliu");
        //找到值就返回 找不到值就设置默认值
        String one = list.stream().filter(item -> "李四".equals(item)).findAny().orElse(null);
        String noFind = list.stream().filter(item -> "李si".equals(item)).findAny().orElse(null);
        System.out.println(one);
        System.out.println(noFind);

        Stream<Integer> stream = Stream.of(6, 4, 6, 7, 3, 9, 8, 10, 12, 14, 14);
        Stream<Integer> newStream = stream.filter(s -> s > 5) //6 6 7 9 8 10 12 14 14
                .distinct() //6 7 9 8 10 12 14
                .skip(2) //9 8 10 12 14
                .limit(2); //9 8
        newStream.forEach(System.out::println);

    }

    /**
     * 定制排序 comparing默认升序
     * 可以使用reversed 翻转排序
     */
    private static void sorted() {
        List<String> list = Arrays.asList("aa", "ff", "dd");
        //String 类自身已实现Compareable接口
        list.stream().sorted().forEach(System.out::println);// aa dd ff

        List stuList = new ArrayList(4);
        stuList.add(new Student(1, "aa", 12));
        stuList.add(new Student(2, "bb", 13));
        stuList.add(new Student(3, "aaa", 11));
        stuList.add(new Student(4, "aa", 9));
        //先按名称升序再按照年龄升序
        Stream<Student> stream = stuList.stream().sorted(Comparator.comparing(Student::getName).thenComparing(Student::getAge));
        stream.forEach(System.out::println);
    }


}

